package com.qd.panda.gas.discount.autohome;

import com.cdqidi.exception.ApiException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qd.common.sys.domain.entity.log.SendLogDTO;
import com.qd.panda.gas.discount.autohome.req.OrderDTO;
import com.qd.panda.gas.discount.autohome.resp.AutoHomeResponseDTO;
import com.qd.panda.gas.station.base.BaseHttpResponseUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * 对接汽车之家优惠信息
 *
 * @author sjk
 * @create 2022-11-14 10:51
 * @since 1.0.0
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class AutoHomeHttpServiceImpl {
    private static final String TOKEN = "2fbd7eed8457b9b0129171c99f3eb2bc";
    /**
     * 获取今日优惠
     */
    public static final String TODAY_URL = "http://39.100.39.184/api/preferential/today";
    /**
     * 关联订单优惠
     */
    private static final String ORDER_URL = "http://39.100.39.184/api/preferential/order?order_no=";

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    /**
     * 拉取今日优惠
     */
    public BigDecimal toDay(SendLogDTO sendLogDTO) {
        final long start = System.currentTimeMillis();
        try {
            sendLogDTO.setUrl(TODAY_URL);
            sendLogDTO.setReqMethod(HttpMethod.GET.name());
            MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
            header.add("token", TOKEN);
            HttpEntity<Object> httpEntity = new HttpEntity<>(header);
            final AutoHomeResponseDTO autoHomeResponseDTO = build(() -> restTemplate.exchange(TODAY_URL, HttpMethod.GET, httpEntity, String.class), Arrays.asList(HttpStatus.OK.value(), HttpStatus.CREATED.value()));
            sendLogDTO.setResponseMsg(autoHomeResponseDTO.getData().toString());
            return autoHomeResponseDTO.getData().decimalValue();
        } finally {
            final long end = System.currentTimeMillis();
            sendLogDTO.setTimeConsumer(end - start);
        }

    }

    /**
     * 关联订单优惠
     *
     * @param orderDTO 壳牌方的订单ID
     */
    @Retryable(value = ResourceAccessException.class, maxAttempts = 4, backoff = @Backoff(delay = 500L, multiplier = 2))
    public void order(OrderDTO orderDTO) {
        final long start = System.currentTimeMillis();
        final SendLogDTO sendLogDTO = orderDTO.getSendLogDTO();
        sendLogDTO.setUrl(ORDER_URL);
        try {
            sendLogDTO.setReqParam(objectMapper.writeValueAsString(orderDTO));
        } catch (JsonProcessingException ignored) {
        }
        sendLogDTO.setReqMethod(HttpMethod.POST.name());
        MultiValueMap<String, String> header = new LinkedMultiValueMap<>();
        header.add("token", TOKEN);
        HttpEntity<Object> httpEntity = new HttpEntity<>(orderDTO, header);
        try {
            build(() -> restTemplate.exchange(ORDER_URL, HttpMethod.POST, httpEntity, String.class), Arrays.asList(HttpStatus.OK.value(), HttpStatus.CREATED.value()));
        } finally {
            final long end = System.currentTimeMillis();
            sendLogDTO.setTimeConsumer(end - start);
        }
    }

    private AutoHomeResponseDTO build(Supplier<ResponseEntity<String>> supplier, List<Integer> successHttpStatusList) {
        return (AutoHomeResponseDTO) BaseHttpResponseUtil.build(supplier, this::buildShellResponseDTO, successHttpStatusList);
    }

    private AutoHomeResponseDTO build(Supplier<ResponseEntity<String>> supplier) {
        return (AutoHomeResponseDTO) BaseHttpResponseUtil.build(supplier, this::buildShellResponseDTO);
    }

    private AutoHomeResponseDTO buildShellResponseDTO(JsonNode jsonNode) {
        if (null != jsonNode) {
            AutoHomeResponseDTO shellResponseDTO = new AutoHomeResponseDTO();
            final JsonNode codeJsonNode = Optional.ofNullable(jsonNode.get("resp_code")).orElseThrow(() -> new ApiException("resp_code不存在,json：" + jsonNode));
            final JsonNode messageJsonNode = Optional.ofNullable(jsonNode.get("resp_msg")).orElseThrow(() -> new ApiException("resp_msg不存在,json：" + jsonNode));
            final JsonNode data = Optional.ofNullable(jsonNode.get("data")).orElseThrow(() -> new ApiException("data不存在,json：" + jsonNode));
            shellResponseDTO.setErrCode(codeJsonNode.intValue());
            shellResponseDTO.setErrMsg(messageJsonNode.asText());
            shellResponseDTO.setData(data);
            return shellResponseDTO;
        }
        return null;
    }
}